"""
    异步：
       轻量级的线程--协程
       可以获取异步函数的返回值
       主进程需要异步才行
       更适合文件读写使用
    异步与多线程多进程
        多进程多线程更适合业务方向的处理，不需要返回值的工作
    async、await与asyncio模块
        async def test():
            return 'a'
        async def handle():
            result = await test()
            print(result)

        最上层一定是一个异步的，所以可以用python内置的asyncio

        gather  将异步函数批量执行   asyncfunc...    List函数的返回结果
        run     执行主异步函数      [task]          执行函数的返回结果

    gevent python2已经存在了
    pip install gevent
    windows环境下需要 Microsoft Visual C++
    pip install wheel

    spawn   创建协程对象  Func,args   返回协程对象
    joinall 批量处理协程对象 [spawnobj] [spawnobj]

"""
import asyncio,time,gevent
import os
import random


async def a():
    # time.sleep(2) cpu级别的阻塞，是同步的 所以异步不会生效
    await asyncio.sleep(2)
    return 'a function'

async def b():
    await asyncio.sleep(3)
    return 'b function'

async def main():
    result =  await asyncio.gather(
        a(), b()
    )
    print(result)


print('-----------------[python 2 version  used gevent package.]----------------------')
def gevent_a():
    for i in range(5):
        print(i, 'gevent_a', os.getpid())
        gevent.sleep(random.random() * 2)
    return 'gevent_a result'

def gevent_b():
    for i in range(5):
        print(i, 'gevent_b', os.getpid())
        gevent.sleep(random.random() * 2 )
    return 'gevent_b result'

print('=----------------[end example for python 2 of gevent package.]------------------')

if __name__ == '__main__':
    # 使用asynio演示异步执行
    # start = time.time()
    # asyncio.run(main())
    # end = time.time()
    # print(end - start)

    '''
        ['a function', 'b function']
        3.001206159591675
    '''

    # 使用gevent演示异步执行
    start = time.time()
    g_a = gevent.spawn(gevent_a)
    g_b = gevent.spawn(gevent_b)
    gevent_list = [g_a, g_b]
    result = gevent.joinall(gevent_list)
    print([item.get() for item in result])
    end = time.time()
    print(end - start)